#include "board.h"
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#define dll 30

Board::Board(QWidget *parent) : QWidget(parent), ui(new Ui::wiwi){
    ui->setupUi(this);
    ui->label->setFont(font);
    ui->label_2->setFont(font);
    ui->label_3->setFont(font);
    ui->label_4->setFont(font);
    this->_r = 20;
    setMinimumSize(_r*18+1, _r*20+1);
    init(true);
    time=dll;
    showtime();
    startTimer(1000);
}

Board::~Board(){

}

void Board::init(bool bRedSide){
    for(int i=0; i<32; ++i){
        _s[i].init(i);
    }
    if(bRedSide){
        for(int i=0; i<32; ++i){
            _s[i].rotate();
        }
    }

    _selectid = -1;
    go=3;
    _bRedTurn = true;
    _bSide = bRedSide;
    update();
}

void Board::paintEvent(QPaintEvent *){
    QPainter paint(this);
    QRect rect=this->rect();
    QRect q1(200,50,250,250);
    paint.drawPixmap(q1,QPixmap("://img/b.png"));
    QRect q2(200,400,250,250);
    paint.drawPixmap(q2,QPixmap("://img/r.png"));
    QRect q3(600,400,150,200);
    paint.drawPixmap(q3,QPixmap("://img/si.png"));
    QRect q4(600,50,150,200);
    paint.drawPixmap(q4,QPixmap("://img/si.png"));
    QRect q5(700,290,70,70);
    paint.drawPixmap(q5,QPixmap("://img/board.png"));

    //设置棋盘区域的背景颜色和大小
     QPalette palette;
    // 设置棋盘成了米黄
    QLinearGradient linearGradient(0, 0, 400, 400);
    linearGradient.setColorAt(0.0, QColor(216, 180, 80));
    linearGradient.setColorAt(0.2, QColor(216, 160, 72));
    linearGradient.setColorAt(1.0, QColor(216, 156, 72));
    palette.setBrush(QPalette::Background,  QBrush(linearGradient));
    setPalette(palette);
    setAutoFillBackground(true);
    setMinimumSize(600, 660);

    //画楚河汉界
    QPainter d(this);
    QPointF point(_r*3, _r*10.5);
    d.setFont(QFont("Arial", 21));
    d.drawText(point, "楚河                  汉界");

    int r = height()/20;
    _r = r;
    _off = QPoint(r+1, r+1);

    QPainter p(this);
    p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    p.save();
    drawPlate(p);
    p.restore();

    p.save();
    drawPlace(p);
    p.restore();

    p.save();
    drawInitPosition(p);
    p.restore();

    p.save();
    drawqizi(p);
    p.restore();

}

void Board::drawqizi(QPainter &p){
    for(int i=0; i<32; i++){
        drawqizi(p, i);
    }
}

bool Board::isDead(int id){
    if(id == -1)return true;
    return _s[id]._dead;
}

void Board::drawqizi(QPainter &p, int id){
    if(isDead(id)) return;

    QColor color;
    if(red(id)) color = Qt::red;
    else color = Qt::black;

    p.setPen(QPen(QBrush(color), 2));

    if(id == _selectid) p.setBrush(Qt::gray);
    else p.setBrush(Qt::yellow);

    p.drawEllipse(cell(id));

    p.setFont(QFont("system", _r*1.2, 700));
    p.drawText(cell(id), name(id), QTextOption(Qt::AlignCenter));

}

QString Board::name(int id){
    return _s[id].getText();

}

bool Board::red(int id){
    return _s[id]._red;
}

//绘制停点
void Board::drawInitPosition(QPainter &p, int row, int col)
{
    QPoint pt = center(row, col);
    QPoint off = QPoint(_r/6, _r/6);
    int len = _r/3;

    QPoint ptStart;
    QPoint ptEnd;

    if(col != 0){
        ptStart = QPoint(pt.x() - off.x(), pt.y() - off.y());
        ptEnd = ptStart + QPoint(-len, 0);
        p.drawLine(ptStart, ptEnd);
        ptEnd = ptStart + QPoint(0, -len);
        p.drawLine(ptStart, ptEnd);

        ptStart = QPoint(pt.x() - off.x(), pt.y() + off.y());
        ptEnd = ptStart + QPoint(-len, 0);
        p.drawLine(ptStart, ptEnd);
        ptEnd = ptStart + QPoint(0, +len);
        p.drawLine(ptStart, ptEnd);
    }

    if(col != 8){
        ptStart = QPoint(pt.x() + off.x(), pt.y() + off.y());
        ptEnd = ptStart + QPoint(+len, 0);
        p.drawLine(ptStart, ptEnd);
        ptEnd = ptStart + QPoint(0, +len);
        p.drawLine(ptStart, ptEnd);

        ptStart = QPoint(pt.x() + off.x(), pt.y() - off.y());
        ptEnd = ptStart + QPoint(+len, 0);
        p.drawLine(ptStart, ptEnd);
        ptEnd = ptStart + QPoint(0, -len);
        p.drawLine(ptStart, ptEnd);
    }
}

void Board::drawInitPosition(QPainter &p){
    drawInitPosition(p, 3, 0);
    drawInitPosition(p, 3, 2);
    drawInitPosition(p, 3, 4);
    drawInitPosition(p, 3, 6);
    drawInitPosition(p, 3, 8);
    drawInitPosition(p, 6, 0);
    drawInitPosition(p, 6, 2);
    drawInitPosition(p, 6, 4);
    drawInitPosition(p, 6, 6);
    drawInitPosition(p, 6, 8);
    drawInitPosition(p, 2, 1);
    drawInitPosition(p, 2, 7);
    drawInitPosition(p, 7, 1);
    drawInitPosition(p, 7, 7);
}

//画米字格
void Board::drawPlace(QPainter &p){
    p.drawLine(center(0, 3), center(2, 5));
    p.drawLine(center(2, 3), center(0, 5));
    p.drawLine(center(9, 3), center(7, 5));
    p.drawLine(center(7, 3), center(9, 5));
}

//绘制棋盘
void Board::drawPlate(QPainter &p){
    QPen pen(Qt::SolidLine);
    //画10条横线
    for(int i=0;i<10;i++){
        if(i==0 || i==9){
             pen.setWidth(4);
             p.setPen(pen);
        }
        else{
           pen.setWidth(2);
           p.setPen(pen);
        }
        p.drawLine(center(i, 0), center(i, 8));
    }
    //画9条竖线
    for(int i=0;i<9;i++){
        if(i==0||i==8){
            pen.setWidth(4);
            p.setPen(pen);
            p.drawLine(center(0, i), center(9, i));
        }
        else{
            pen.setWidth(2);
            p.setPen(pen);
            p.drawLine(center(0, i), center(4, i));
            p.drawLine(center(5, i), center(9, i));
        }
    }
}

QPoint Board::center(int row, int col){
    QPoint pt(_r*col*2, _r*row*2);
    return pt + _off;
}

QPoint Board::center(int id){
    return center(_s[id]._row, _s[id]._col);
}

QPoint Board::topLeft(int row, int col){
    return center(row, col) - QPoint(_r, _r);
}

QPoint Board::topLeft(int id){
    return center(id) - QPoint(_r, _r);
}

QRect Board::cell(int row, int col){
    return QRect(topLeft(row, col), QSize(_r*2-1, _r*2-1));
}

QRect Board::cell(int id){
    return QRect(topLeft(id), QSize(_r*2-1, _r*2-1));
}

bool Board::getClickRowCol(QPoint pt, int &row, int &col){
    for(row=0; row<=9; ++row){
        for(col=0; col<=8; ++col){
            QPoint distance = center(row, col) - pt;
            if(distance.x() * distance.x() + distance.y() * distance.y() < _r* _r){
                return true;
            }
        }
    }
    return false;
}

void Board::mouseReleaseEvent(QMouseEvent *ev){
    if(ev->button() != Qt::LeftButton)
    {
        return;
    }
    if(ev->x()<=1500 && ev->x()<=980 &&ev->y()<=800 &&ev->y()<=400&&go==3)
    {
        ui->label->setText("游");
        ui->label_2->setText("戏");
        ui->label_3->setText("开");
        ui->label_4->setText("始");
        go=1;
    }

    if(keep==(qizi::JIANG)){
         go=-2;
         ui->label->setText("游");
         ui->label_2->setText("戏");
         ui->label_3->setText("结");
         ui->label_4->setText("束");
    }

    click(ev->pos());
}

bool Board::canselect(int id){
    return _bRedTurn == _s[id]._red;
}

void Board::tryselectqizi(int id){
    if(id == -1){
        return;
    }
    if(!canselect(id)) {
        return;
    }
    _selectid = id;
    update();
}

bool Board::samecolor(int id1, int id2){
    if(id1 == -1 || id2 == -1) {
        return false;
    }
    return red(id1) == red(id2);
}

void Board::trymoveqizi(int killid, int row, int col){
    if(killid != -1 && samecolor(killid, _selectid)){
        tryselectqizi(killid);
        return;
    }

    bool ret = canMove(_selectid, killid, row, col);
    if(ret){
        moveqizi(_selectid, killid, row, col);
        _selectid = -1;
        update();
    }
}

int Board::getqiziCountAtline(int row1, int col1, int row2, int col2){
    int ret = 0;
    if(row1 != row2 && col1 != col2){
        return -1;
    }
    if(row1 == row2 && col1 == col2){
        return -1;
    }
    if(row1 == row2){
        int min = col1 < col2 ? col1 : col2;
        int max = col1 < col2 ? col2 : col1;
        for(int col = min+1; col<max; ++col){
            if(getqiziId(row1, col) != -1) {
                ++ret;
            }
        }
    }
    else{
        int min = row1 < row2 ? row1 : row2;
        int max = row1 < row2 ? row2 : row1;
        for(int row = min+1; row<max; ++row){
            if(getqiziId(row, col1) != -1) {
                ++ret;
            }
        }
    }

    return ret;
}

bool Board::canMoveJIANG(int moveid, int killid, int row, int col){
    if(killid != -1 && _s[killid]._type == qizi::JIANG){
        return canMoveCHE(moveid, killid, row, col);
    }

    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int r=abs(dr)*10+abs(dc);
    if(r != 1 && r != 10) {
        return false;
    }
    if(col < 3 || col > 5) {
        return false;
    }
    if(isBottomSide(moveid)){
        if(row < 7) {
            return false;
        }
    }
    else{
        if(row > 2){
            return false;
        }
    }
    return true;
}

bool Board::canMoveSHI(int moveid, int, int row, int col){
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int r=abs(dr)*10+abs(dc);
    if(r != 11) {
        return false;
    }

    if(col < 3 || col > 5) {
        return false;
    }
    if(isBottomSide(moveid)){
        if(row < 7) {
            return false;
        }
    }
    else{
        if(row > 2){
            return false;
        }
    }
    return true;
}

bool Board::canMoveXIANG(int moveid, int, int row, int col){
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int r=abs(dr)*10+abs(dc);
    if(r != 22) {
        return false;
    }
    int rEye = (row+_s[moveid]._row)/2;
    int cEye = (col+_s[moveid]._col)/2;
    if(getqiziId(rEye, cEye) != -1){
        return false;
    }

    if(isBottomSide(moveid)){
        if(row < 4) {
            return false;
        }
    }
    else{
        if(row > 5) {
            return false;
        }
    }
    return true;
}

bool Board::canMoveCHE(int moveid, int, int row, int col){
    int ret = getqiziCountAtline(_s[moveid]._row, _s[moveid]._col, row, col);
    if(ret == 0){
        return true;
    }
    return false;
}

bool Board::canMoveMA(int moveid, int, int row, int col){
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int r=abs(dr)*10+abs(dc);
    if(r != 12 && r != 21){
        return false;
    }
    if(r == 12){
        if(getqiziId(_s[moveid]._row, (col+_s[moveid]._col)/2) != -1)
            return false;
    }
    else{
        if(getqiziId((row+_s[moveid]._row)/2, _s[moveid]._col) != -1)
            return false;
    }

    return true;
}

bool Board::canMovePAO(int moveid, int killid, int row, int col){
    int ret = getqiziCountAtline(row, col, _s[moveid]._row, _s[moveid]._col);
    if(killid != -1){
        if(ret == 1) return true;
    }
    else{
        if(ret == 0) return true;
    }
    return false;
}

bool Board::canMoveBING(int moveid, int, int row, int col){
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int r=abs(dr)*10+abs(dc);
    if(r != 1 && r != 10){
        return false;
    }
    if(isBottomSide(moveid)){
        if(row >_s[moveid]._row) return false;
        if(_s[moveid]._row >= 5 && row == _s[moveid]._row) return false;
    }
    else{
        if(row < _s[moveid]._row) return false;
        if(_s[moveid]._row <= 4 && row == _s[moveid]._row) return false;
    }
    return true;
}

bool Board::canMove(int moveid, int killid, int row, int col){
    if(samecolor(moveid, killid)){
        return false;
    }

    switch (_s[moveid]._type){
    case qizi::CHE:
        return canMoveCHE(moveid, killid, row, col);
        break;
    case qizi::MA:
        return canMoveMA(moveid, killid, row, col);
        break;
    case qizi::PAO:
        return canMovePAO(moveid, killid, row, col);
        break;
    case qizi::BING:
        return canMoveBING(moveid, killid, row, col);
        break;
    case qizi::JIANG:
        return canMoveJIANG(moveid, killid, row, col);
        break;
    case qizi::SHI:
        return canMoveSHI(moveid, killid, row, col);
        break;
    case qizi::XIANG:
        return canMoveXIANG(moveid, killid, row, col);
        break;
    }
    return false;
}

void Board::reliveqizi(int id){
    if(id==-1) return;
    _s[id]._dead = false;
}

void Board::killqizi(int id){
    if(id==-1) return;
    _s[id]._dead = true;
}

bool Board::isBottomSide(int id){
    return _bSide == _s[id]._red;
}

void Board::moveqizi(int moveid, int row, int col){
    _s[moveid]._row = row;
    _s[moveid]._col = col;
    _bRedTurn = !_bRedTurn;
}

void Board::saveStep(int moveid, int killid, int row, int col, QVector<Step*>& steps)
{
    Step* step = new Step;
    step->_colFrom = _s[moveid]._col;
    step->_colTo = col;
    step->_rowFrom = _s[moveid]._row;
    step->_rowTo = row;
    step->_moveid = moveid;
    step->_killid = killid;
    steps.append(step);
}

void Board::moveqizi(int moveid, int killid, int row, int col)
{
    saveStep(moveid, killid, row, col, _steps);

    killqizi(killid);
    moveqizi(moveid, row, col);
}

void Board::click(int id, int row, int col)
{
    if(this->_selectid == -1)
    {
        keep=_s[id]._type;
        if(go==1){
            go=2;
            ui->label->setText("红");
            ui->label_2->setText("方");
            ui->label_3->setText("进");
            ui->label_4->setText("行");
        }
        else if(go==2){
            go=1;
            ui->label->setText("黑");
            ui->label_2->setText("方");
            ui->label_3->setText("进");
            ui->label_4->setText("行");
        }
        time=dll;
        tryselectqizi(id);
    }
    else
    {
        trymoveqizi(id, row, col);
    }
}

void Board::click(QPoint pt)
{
    int row, col;
    bool bClicked = getClickRowCol(pt, row, col);
    if(!bClicked) return;

    int id = getqiziId(row, col);
    click(id, row, col);
}

int Board::getqiziId(int row, int col)
{
    for(int i=0; i<32; ++i)
    {
        if(_s[i]._row == row && _s[i]._col == col && !isDead(i))
            return i;
    }
    return -1;
}

void Board::back(Step *step)
{
    reliveqizi(step->_killid);
    moveqizi(step->_moveid, step->_rowFrom, step->_colFrom);
}

void Board::backone()
{
    if(this->_steps.size() == 0) return;

    Step* step = this->_steps.last();
    _steps.removeLast();
    back(step);

    update();
    delete step;
}

void Board::back()
{
    backone();
}

void Board::slotBack()
{
    back();
}

void Board::showtime()
{
   texttime=QString::number(time,10);
   ui->lcdNumber->display(texttime);
}

//设置倒计时
void Board::timerEvent(QTimerEvent *event)
{
   if((go==1||go==2)&&time>=1)
   {
       time--;
       showtime();
   }
   else if(go==-2)
   {
       time=0;
       showtime();
   }
}
